#include "smartptr.hpp"
#include <string>
//#include <memory>
using namespace ns_smartptr;

void division(int a, int b)
{
    if(b == 0)
    {
        throw "division 0 error";
    }
        
    std::cout << "a / b = " << a / b << std::endl;
}

void func()
{
    int a = 0;
    int b = 0;
    //int* p = new int[5];
    auto_ptr<int> ap(new int);
    std::cin >> a >> b;
    division(a, b);
    //delete[] p;
    //std::cout << "delete p" << std::endl;
}

void Test1()
{
    auto_ptr<int> ap(new int);
    *ap = 1;
    std::cout << *ap << std::endl;
    std::cout << ap.get() << std::endl;
    auto_ptr<int> pp(ap);
    if(ap.get() == nullptr)
        std::cout << "ap is a nullptr" << std::endl;
    *pp = 3;
    std::cout << *pp << std::endl;
    std::cout << pp.get() << std::endl;
}

void Test2()
{
    unique_ptr<int> up(new int);
    *up = 10;
    std::cout << *up << std::endl;
    //unique_ptr<int> copy(up);
}

void Test3()
{
    shared_ptr<int> sp1(new int);
    *sp1 = 20;
    std::cout << *sp1 << std::endl;
    std::cout << sp1.use_count() << std::endl;
    shared_ptr<int> sp2(sp1);
    shared_ptr<int> sp3(sp1);
    std::cout << sp3.use_count() << std::endl;
    std::cout << "sp1 : " << sp1.get() << std::endl;
    std::cout << "sp2 : " << sp2.get() << std::endl;
    std::cout << "sp3 : " << sp3.get() << std::endl;
    std::cout << std::endl;

    shared_ptr<int> sp4(new int);
    sp1 = sp4;
    std::cout << "sp1 : " << sp1.get() << std::endl;
    std::cout << sp1.use_count() << std::endl;
    std::cout << "sp2 : " << sp2.get() << std::endl;
    std::cout << sp2.use_count() << std::endl;
}

struct ListNode
{
public:
    ListNode() = default;
    int _val;
    shared_ptr<ListNode> _prev;
    shared_ptr<ListNode> _next;
    // weak_ptr<ListNode> _prev;
    // weak_ptr<ListNode> _next;
};

void Test4()
{
    shared_ptr<ListNode> n1(new ListNode);
    shared_ptr<ListNode> n2(new ListNode);
    std::cout << n1.use_count() << std::endl;
    std::cout << n2.use_count() << std::endl;
    
    n1->_next = n2;
    n2->_prev = n1;

    std::cout << n1.use_count() << std::endl;
    std::cout << n2.use_count() << std::endl;
}

int main()
{
    // try
    // {
    //     func();
    // }
    // catch(const char* s)
    // {
    //     std::cout << s << std::endl;
    // }
    // catch(...)
    // {}

    //Test1();
    //Test2();
    //Test3();
    //Test4();
    Test();

    return 0;
}